//--------------------------------------------------------------------------
// 
//  Copyright (c) Chili Software.  All rights reserved. 
// 
//  File: RelationInformation.cs
//
//  Description: A class holding information for a relation.
// 
//--------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using Chili.Opf3.Mapping;

namespace Chili.Opf3.Relations
{
	/// <summary>
	/// This class holds the most important informations for a relation.
	/// </summary>
	public sealed class RelationInformation
	{
		private object _parent;
		private Type _relatedType;
		private RelationAttribute _attribute;
		private ObjectContext _context;

		/// <summary>
		/// Creates a new instance of the <see cref="RelationInformation">RelationInformation Class</see>.
		/// </summary>
		/// <param name="parent">The parent object itself.</param>
		/// <param name="relatedType">The child type of the relation.</param>
		/// <param name="attribute">The <see cref="RelationAttribute">RelationAttribute</see> specified on the relation</param>
		/// <param name="objectContext">The current <see cref="ObjectContext">ObjectContext</see> used to load the parent object.</param>
		internal RelationInformation(object parent, Type relatedType, RelationAttribute attribute, ObjectContext objectContext)
		{
			if (parent == null)
				throw new ArgumentNullException("parent");
			if (relatedType == null)
				throw new ArgumentNullException("relatedType");
			if (attribute == null)
				throw new ArgumentNullException("attribute");
			if (objectContext == null)
				throw new ArgumentNullException("objectContext");

			_parent = parent;
			_relatedType = relatedType;
			_attribute = attribute;
			_context = objectContext;
		}

		/// <summary>
		/// Gets the <see cref="ObjectContext">ObjectContext</see> instance that has been used to load 
		/// the parent object.
		/// </summary>
		public ObjectContext Context
		{
			get { return _context; }
		}

		/// <summary>
		/// Gets the <see cref="RelationAttribute">RelationAttribute</see> that is set on the relation.
		/// </summary>
		public RelationAttribute Attribute
		{
			get { return _attribute; }
		}

		/// <summary>
		/// Gets the related type. Seen from the object that has implemented the 
		/// <see cref="IRelationsPopulateHelper">IRelationsPopulateHelper</see> interface.
		/// </summary>
		public Type RelatedType
		{
			get { return _relatedType; }
		}

		/// <summary>
		/// Gets the parent type. It is the type of the persistent that implemented the 
		/// <see cref="IRelationsPopulateHelper">IRelationsPopulateHelper</see> interface.
		/// </summary>
		public Type ParentType
		{
			get { return _parent.GetType(); }
		}

		/// <summary>
		/// Returns the class that inherits from <see cref="ObjectHolderBase">ObjectHolderBase</see>. Classes
		/// inheriting from that class are holding related objects.
		/// </summary>
		public ObjectHolderBase GetObjectHolder()
		{
			// Get the mapping for the parent.
			TypeMapping mapping = TypeMapping.GetTypeMapping(_parent);
			// Get the relation infor object.
			IRelationInfo info = mapping.Relations.GetRelationMapping(_attribute.Name);
			return info.GetObjectHolder(_parent);
		}
	}
}
